package ru.iasokolov.demo

import org.springframework.boot.CommandLineRunner
import org.springframework.core.ResolvableType
import org.springframework.stereotype.Service
import ru.iasokolov.demo.entity.AbstractBaseEntity
import ru.iasokolov.demo.entity.AbstractBaseRepository
import ru.iasokolov.demo.entity.address.Address
import ru.iasokolov.demo.entity.address.AddressData
import ru.iasokolov.demo.entity.address.AddressRepo
import ru.iasokolov.demo.entity.persdata.Persdata
import ru.iasokolov.demo.entity.persdata.PersdataData
import ru.iasokolov.demo.entity.persdata.PersdataRepo
import java.time.LocalDate
import java.util.*

@Service
class CommandLineRunner(
    private val repos: Repos<AbstractBaseEntity>,
    private val addressRepo: AddressRepo,
    private val persdataRepo: PersdataRepo
) : CommandLineRunner {
    override fun run(vararg args: String?) {

        val recordAddress = saveRecord(
            record = Address(
                id = UUID.randomUUID(),
                startDate = LocalDate.now(),
                endDate = LocalDate.now(),
                deleted = false,
                dataType = "1",
                data = AddressData(fullAddress = "fullAddress")
            )
        )

        println(recordAddress)

        val recordPersdata = saveRecord(
            record = Persdata(
                id = UUID.randomUUID(),
                startDate = LocalDate.now(),
                endDate = LocalDate.now(),
                deleted = false,
                dataType = "1",
                data = PersdataData(name = "fullName")
            )
        )

        println(recordPersdata)

        println("end-of-program")


//
//        val recordOne = Address(
//            id = UUID.randomUUID(),
//            startDate = LocalDate.now(),
//            endDate = LocalDate.now(),
//            deleted = false,
//            dataType = "1",
//            data = AddressData(fullAddress = "")
//        ).toDataRecord()
//
//        val recordTwo = Address(
//            id = UUID.randomUUID(),
//            startDate = LocalDate.now(),
//            endDate = LocalDate.now(),
//            deleted = false,
//            dataType = "2",
//            data = AddressData(fullAddress = "")
//        ).toDataRecord()
//
//
//        val records = TimeDependencyRecordService().sliceRecords(
//            newRecord = newRecord,
//            currentRecords = listOf(recordOne, recordTwo)
//        )
//
//        val changeRecords = records.map { it as Address }
    }

    fun saveRecord(record: AbstractBaseEntity): AbstractBaseEntity {
        val type = ResolvableType.forClassWithGenerics(AbstractBaseRepository::class.java, record.javaClass)
        val repo = repos.getAllRepository().firstOrNull { type.isInstance(it) }

        return repo?.save(record) ?: throw RuntimeException("Repo not found")
    }
}

@Service
class Repos<Entity : AbstractBaseEntity>(
    private val repos: List<AbstractBaseRepository<Entity>>
) {
    fun getAllRepository(): List<AbstractBaseRepository<Entity>> {
        return repos
    }
}
